package com.ship.dispatch.bpm.utils;

import com.ship.common.core.utils.DateUtil;

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 *@title CalculateDateUtil
 *@description 计算流程任务超期时间
 *@author yl
 *@create 2023/12/14 0014
 */

public class CalculateDateUtil {

    private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"};

    private final static SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
    private final static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
    private final static SimpleDateFormat sdfDays = new SimpleDateFormat("yyyyMMdd");
    private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final static SimpleDateFormat sdfTimes = new SimpleDateFormat("yyyyMMddHHmmss");
    private final static SimpleDateFormat days = new SimpleDateFormat("dd");
    private final static SimpleDateFormat month = new SimpleDateFormat("MM");


    /**
     * 获取  当前年   YYYY格式
     *
     * @return
     */
    public static String getSdfTimes(Date date) {
        if(date==null) return "";
        return sdfTimes.format(date);
    }

    public static String pasrseDate(Date date){
        if(date==null){
            return "";
        }
        return sdfDay.format(date);
    }
    public static String pasrseDates(Date date){
        if(date==null){
            return "";
        }
        return sdfTime.format(date);
    }
    public static Date pasrseDate(String date){
        Date tempDate = null;
        try {
            SimpleDateFormat sdf1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
            tempDate = sdf1.parse(date);

        } catch (ParseException e) {
            try {
                tempDate = sdfTime.parse(date);
            } catch (ParseException ex) {
            }
        }
        return tempDate;
    }

    public static void main(String[] args) {
        float   f   =  34.177789f;
        BigDecimal b  =   new BigDecimal(f);
        DecimalFormat decimalFormat = new DecimalFormat("#0.0000");
        System.out.println(Float.parseFloat(decimalFormat.format(b)));
    }

    /**
     * 获取  当日
     *
     * @return
     */
    public static String getYears(Date date) {
        if(date==null) return "";
        return sdfYear.format(date);
    }
    /**
     * 获取  当日
     *
     * @return
     */
    public static String getDays(Date date) {
        if(date==null) return "";
        return days.format(date);
    }

    /**
     * 获取  当日
     *
     * @return
     */
    public static String getMonths(Date date) {
        if(date==null) return "";
        return month.format(date);
    }

    /**
     * 计算任务超时
     * @param expectedLoadingDate 起始日期
     * @param expectedLoadingWorkDateLength 工作日时长
     * @param expectedLoadingFreeDateLength 自由日时长
     * @return
     */
    public static LocalDate calculateDate(String expectedLoadingDate,Integer expectedLoadingWorkDateLength,Integer expectedLoadingFreeDateLength,String workDays,String freeDays){
       List<String> works = Arrays.stream(workDays.split(",")).collect(Collectors.toList());
       List<String> frees = Arrays.stream(freeDays.split(",")).collect(Collectors.toList());
        Date formMa = null;
        if(expectedLoadingDate ==null){
            return null;
        }
        try {

            formMa = sdfDay.parse(expectedLoadingDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String tmp = sdfDay.format(formMa);
        LocalDate startDate =  LocalDate.parse(tmp);
        LocalDate wordDate = null;
        LocalDate freeDay = null;
        if(expectedLoadingWorkDateLength !=null){
            wordDate = addWorkDays(startDate,expectedLoadingWorkDateLength,works,frees);
        }
        if(expectedLoadingFreeDateLength != null){
            if(expectedLoadingFreeDateLength>0){
                freeDay = startDate.minusDays(expectedLoadingFreeDateLength);
            }else{
                freeDay = startDate.plusDays(-expectedLoadingFreeDateLength);
            }
        }
        if(wordDate == null){
            return freeDay;
        }
        if(freeDay==null){
            return wordDate;
        }
        if(wordDate.compareTo(freeDay)>0){
            return wordDate;
        }
        return freeDay;
    }
    /**
     * 计算两个日期之间相差的天数  zc
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            smdate = sdf.parse(sdf.format(smdate));
            bdate = sdf.parse(sdf.format(bdate));

        } catch (ParseException e) {
            e.printStackTrace();
            return -1;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 得到n天之后的日期
     *
     * @param days
     * @return
     */
    public static String getAfterDayDate(String days) {
        int daysInt = Integer.parseInt(days);

        Calendar canlendar = Calendar.getInstance(); // java.util包
        canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动
        Date date = canlendar.getTime();

        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdfd.format(date);

        return dateStr;
    }
    /**
     *得到截止工作日，比如 10.1为周一 增加5天，得到10.6，如果其中有一天为周六，则得到10.7以此类推
     * @param date 当前时间
     * @param days 需要增加的天数
     * @param strings 特殊工作日
     * @param strings1 特殊休息日
     * @return
     */
    public static LocalDate addWorkDays(LocalDate date, int days, List<String> strings, List<String> strings1) {
        int addedDays = 0;
        boolean flag = true;
        if(days<0){
            flag = false;
            days = -days;
        }
        while (addedDays < days) {
            if(flag){
                date = date.minusDays(1);
            }else{
                date = date.plusDays(1);
            }
            if (isWorkDay(date)) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String dateString = date.format(formatter);
                int a3 = 0;
                for (String localDate : strings1) {
                    if(localDate.equals(dateString)){
                        a3++;
                    }
                }
                if(a3==0){
                    addedDays++;
                }
            }else {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String dateString = date.format(formatter);
                for (String localDate : strings) {
                    if(localDate.equals(dateString)){
                        addedDays++;
                        break;
                    }
                }
            }
        }
        return date;
    }

    private static boolean isWorkDay(LocalDate date) {
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
    }

    /**
     * 计算两个日期相差天数
     * @param date1
     * @param date2
     * @return
     */
    public static float getBetweenDays(String date1, String date2) {
        try {
            Date d1 = null;
            try{
                d1 = sdfTime.parse(date1);
            }catch (Exception e){
                d1 = sdfDay.parse(date1);
            }
            Date d2 = null;
            try{
                d2 = sdfTime.parse(date2);
            }catch (Exception e){
                d2 = sdfDay.parse(date2);
            }

            Long date1Num = d1.getTime();
            Long date2Num = d2.getTime();
            float days =  ((date2Num-date1Num)/(float)(24*60*60*1000));
            BigDecimal b  =   new BigDecimal(days);
            DecimalFormat decimalFormat = new DecimalFormat("#0.0000");
            //System.out.println(decimalFormat.format(b));

            return Float.parseFloat(decimalFormat.format(b));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0L;
    }



    public static LocalDateTime toLocalDate(Date date){
        if(date!=null){
            Instant instant = date.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
            return localDateTime;
        }
        return null;
    }

}
